#include "globalapplication.h"
#include "appsingleton.hpp"
#include "log.h"
#include <QMouseEvent>
#include <QCursor>
#include <QLocalSocket>
#include <QLocalServer>

// 单实例标识符
static const QString SINGLE_INSTANCE_KEY = "DesktopTimer_SingleInstance_Key";

GlobalApplication::GlobalApplication(int& argc, char** argv)
    : QApplication(argc, argv)
    , m_sharedMemory(nullptr)
    , m_isFirstInstance(false)
{
    // 设置应用程序不在最后一个窗口关闭时退出
    setQuitOnLastWindowClosed(false);

    // 检测单实例（注意：此时日志系统还未初始化，使用qDebug）
    m_sharedMemory = new QSharedMemory(SINGLE_INSTANCE_KEY, this);
    
    // 尝试创建共享内存
    if (m_sharedMemory->attach()) {
        // 已经有实例在运行
        m_isFirstInstance = false;
        qDebug() << "检测到已有实例正在运行";
    } else {
        // 尝试创建共享内存
        if (m_sharedMemory->create(1)) {
            m_isFirstInstance = true;
            qDebug() << "当前为第一个应用实例";
        } else {
            m_isFirstInstance = false;
            qWarning() << "无法创建共享内存，单实例检测可能失败";
        }
    }
}

GlobalApplication::~GlobalApplication()
{
    if (m_sharedMemory && m_isFirstInstance) {
        m_sharedMemory->detach();
    }
    qDebug() << "全局应用程序对象已销毁";
}

bool GlobalApplication::isInstanceRunning() const
{
    return !m_isFirstInstance;
}

void GlobalApplication::activateExistingInstance()
{
    if (!m_isFirstInstance) {
        emit instanceAlreadyRunning();
    }
}

bool GlobalApplication::notify(QObject *obj, QEvent *event)
{
    // 参数有效性检查
    if (!obj || !event) {
        logWarning("notify收到空对象或空事件");
        return false;
    }

    try {
        // 处理不同类型的事件
        switch (event->type()) {
            case QEvent::ApplicationDeactivated:
                // 应用程序失去焦点
                handleApplicationDeactivated();
                break;

            case QEvent::MouseButtonPress:
                // 鼠标按下事件
                handleMousePress(QCursor::pos());
                break;

            case QEvent::NonClientAreaMouseButtonRelease:
                // 非客户区鼠标释放事件（预留）
                // TODO: 可在此处添加特殊处理逻辑
                break;

            default:
                // 其他事件不处理
                break;
        }
    }
    catch (const std::exception& e) {
        logError("全局事件处理异常: " << e.what());
    }
    catch (...) {
        logError("全局事件处理发生未知异常");
    }

    // 继续传递事件到Qt的标准处理流程
    return QApplication::notify(obj, event);
}

void GlobalApplication::handleApplicationDeactivated()
{
    logDebug("应用程序失去焦点，关闭所有弹出窗口");
    
    auto& appSingleton = *CAppSingleton<QWidget>::GetInstance();
    auto objects = appSingleton.GetAllObjects();

    if (objects.isEmpty()) {
        return;
    }

    // 关闭所有可见的弹出窗口
    for (auto* widget : objects) {
        if (widget && widget->isVisible()) {
            try {
                widget->close();
                logDebug("关闭窗口: " << widget->objectName());
            }
            catch (...) {
                logWarning("关闭窗口时发生异常");
            }
        }
    }
}

void GlobalApplication::handleMousePress(const QPoint& globalPos)
{
    auto& appSingleton = *CAppSingleton<QWidget>::GetInstance();
    auto widgets = appSingleton.GetAllObjects();

    if (widgets.isEmpty()) {
        return;
    }

    // 检查所有注册的窗口，如果点击在窗口外部则发送失去焦点事件
    for (auto* widget : widgets) {
        if (widget && widget->isVisible()) {
            closeWidgetIfOutside(widget, globalPos);
        }
    }
}

void GlobalApplication::closeWidgetIfOutside(QWidget* widget, const QPoint& globalPos)
{
    if (!widget) {
        return;
    }

    try {
        // 获取窗口矩形区域
        QRect widgetRect = widget->rect();
        
        // 将全局坐标转换为窗口本地坐标
        QPoint localPos = widget->mapFromGlobal(globalPos);
        
        // 检查点击位置是否在窗口外部
        if (!widgetRect.contains(localPos)) {
            // 发送窗口失去焦点事件
            QEvent windowDeactivate(QEvent::WindowDeactivate);
            QEvent activationChange(QEvent::ActivationChange);
            
            sendEvent(widget, &windowDeactivate);
            sendEvent(widget, &activationChange);
            
            logDebug("窗口失去焦点: " << widget->objectName());
        }
    }
    catch (const std::exception& e) {
        logError("处理窗口点击事件时异常: " << e.what());
    }
    catch (...) {
        logError("处理窗口点击事件时发生未知异常");
    }
}
